package cz.acies.genea.ui.chart;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;

import cz.acies.data.DBConnector;
import cz.acies.data.persist.ModelObject;
import cz.acies.data.persist.TreeNode;
import cz.acies.genea.data.dao.GedFamilyDAO;
import cz.acies.genea.data.dao.GedPersonDAO;
import cz.acies.genea.data.persist.GedFamily;
import cz.acies.genea.data.persist.GedPerson;
import cz.acies.genea.data.persist.GedProject;
import cz.acies.uniql.sql.element.UniQLWhere;
import cz.acies.utils.UIDGenerator;

public class TreeChart
{
	public static void main(String[] args) {
		try {
			/*
			// HOME
			String jdbcUrl = "jdbc:mysql://localhost:3306/gedcom";
			String jdbcDriver = "org.gjt.mm.mysql.Driver";
			
			Properties props = new Properties();
			props.setProperty("user", "root");
			props.setProperty("password", "smart");
			props.setProperty("useUnicode", "true");
			props.setProperty("characterEncoding", "UTF8");
			props.setProperty("characterSetResults", "UTF8");
			*/
			// WORK
			String jdbcUrl = "jdbc:mysql://localhost:3305/gedcom";
			String jdbcDriver = "org.gjt.mm.mysql.Driver";
			
			Properties props = new Properties();
			props.setProperty("user", "root");
			props.setProperty("password", "");
			props.setProperty("useUnicode", "true");
			props.setProperty("characterEncoding", "UTF8");
			props.setProperty("characterSetResults", "UTF8");
			
			String dialectClass = "cz.acies.uniql.dialect.MySQLDialect"; 
			
			DBConnector connector = DBConnector.instance();
			connector.setUrl(jdbcUrl);
			connector.setDriver(jdbcDriver);
			connector.setDialectClass(dialectClass);
			connector.setProps(props);
			connector.initialize();
			
			GedFamilyDAO fDao = new GedFamilyDAO();
			//GedFamily root = fDao.selectById("GE.F.POYD96Q28745JMK"); 		// HOME - Burian Josef
			//GedFamily root = fDao.selectById("GE.F.P35X6LIRJY15WJB"); 		// HOME - Dytrych Zdeněk
			//GedFamily root = fDao.selectById("GE.F.DG6BV9NJJXLESKN"); 		// HOME
			//GedFamily root = fDao.selectById("GE.F.KUGK7AAMBXTQFBI"); 		// WORK
			//GedFamily root = fDao.selectById("GE.F.3VJ4GAOR7ZGFT59"); 		// WORK - Dytrych Zdeněk
			GedFamily root = fDao.selectById("GE.F.QYQ5EAYD4TTEPWL"); 		// HOME - Burian Josef
			
			//System.out.println(root);
			GedPerson selected = root.getMan();

			TreeChart inst = new TreeChart();
			inst.setRoot(root);
			inst.setSelected(selected);
			
			inst.createModel();
			List<Object> list = inst.rendered();
			//System.out.println(html);
			//String html = inst.build();
		} catch (Exception exc) {
			exc.printStackTrace();
		}
	}

	private GedProject project = null;
	private GedFamily root = null;
	private GedPerson selected = null;

	private TreeChartModel model = null;
	
	private GedFamilyDAO fDao;
	private GedPersonDAO pDao;
	
	public TreeChart() {
		this(null, null);
	}

	public TreeChart(GedFamily root, GedPerson selected) {
		fDao = new GedFamilyDAO();
		pDao = new GedPersonDAO();
		setRoot(root);
		setSelected(selected); 
	}

	public List<Object> rendered() throws Exception {
		List<Object> data = new ArrayList<Object>();
		try {
			model = createModel();
			int max = model.getMinRow();
			int min = model.getMaxRow();
			System.out.println(max + ", " + min);
			for (int j = 0; j < max; j++) {
				//ArrayList<TreeChartNode> row = new ArrayList<TreeChartNode>(model.getRows().get(j).values());
				TreeChartRow row = model.getRows().get(j);
				System.out.println(row);
				for (int i = 0; i < row.size(); i++) {
					TreeChartNode node = row.getValue(i);
					if (node.getChildren().isEmpty()) {
						TreeChartNode child = new EmptyTreeChartNode();
						TreeChartCard c1 = child.createLeftCard(child.getFamily().getMan());
						TreeChartCard c2 = child.createRightCard(child.getFamily().getWoman());
						
						int level = node.getLevel() + 1; 
						child.setLevel(level);
						child.setParent(node);
						node.addChild(child);
						
						int x = 0;
						if (i > 0) {
							TreeChartNode prev = row.getValue(i-1);
							if (prev != null) {
								LinkedList<TreeNode> children = new LinkedList<TreeNode>(prev.getChildren());
								TreeChartNode prevLastChild = (TreeChartNode) children.getLast();
								x = model.getRows().get(j+1).indexOf(prevLastChild.getId());
								System.out.println("" + prevLastChild);
							}
						}
						System.out.println("x: " + x);
						
						TreeChartRow map = model.getRows().get(level);
						if (map == null)  map = new TreeChartRow(level);
						map.put(x, child.getId(), child); 
						model.getRows().put(level, map);
						model.getCells().put(child.getId(), child);
		
					}
				}
			}
			
			for (int j = max; j >= 0; j--) {	
				double top = (j - min) * (TreeChartCard.DEFAULT_HEIGHT + 20);
				double left = 0; 
				int xxx = 0;
				Vector<TreeChartNode> row = new Vector<TreeChartNode>(model.getRows().get(j).values());
				for (int i = 0; i < row.size(); i++) {
					TreeChartNode node = row.get(i);
					//System.out.println("-------------------------------------");
					//System.out.println(node);
					node.oy = top;
					if (j == max) {
						if (i == 0) {
							//System.out.println(node + " - " + node.getParent());
							//System.out.println(node + " - " + node.getParent());
							node.ox = 10;
						} else {
							node.ox = row.get(i-1).getRight() + 10;
						}
						
						//model.getRows().get(j).put(node.getFamily().getId(), node);
						//TreeChartNode n = model.getRows().get(j).get(node.getFamily().getId());
					} else {
						if (j > 0) {
							if (!node.getChildren().isEmpty()) {
								Map<String, TreeChartNode> r = model.getRows().get(j+1);
								TreeChartNode firstChild = r.get(((TreeChartNode) node.getChildren().get(0)).getId());
								TreeChartNode lastChild = r.get(((TreeChartNode) node.getChildren().get(node.getChildren().size() - 1)).getId());
								left = firstChild.getLeft() + ((lastChild.getRight() - firstChild.getLeft()) / 2) -(node.width / 2);
								node.ox = left;
							} else {
								node.ox = left;
								if (i == 0) {
									left = node.ox = 10;
								} else {
									left = row.get(i-1).getRight() + 10;
								}
								//shiftChildrenRows(node, TreeChartNode.DEFAULT_WIDTH, j+1, i, max);
							}
						} else if (j == 0) {
							if (!node.getFamily().getChildren().isEmpty()) {
								LinkedList<String> l = new LinkedList<String>(node.getFamily().getChildren().keySet());
								GedPerson firstPerson = model.getProject().getPeople().get(l.getFirst());
								GedPerson lastPerson = model.getProject().getPeople().get(l.getLast());
								String fid1 = new LinkedList<String>(firstPerson.getPartners().keySet()).getFirst();
								String fidn = new LinkedList<String>(lastPerson.getPartners().keySet()).getLast();
								TreeChartNode firstChild = model.getRows().get(j+1).get(fid1);
								TreeChartNode lastChild = model.getRows().get(j+1).get(fidn);
								//Map<String, TreeChartNode> r = model.getRows().get(j+1);
								left = firstChild.getLeft() + ((lastChild.getRight() - firstChild.getLeft()) / 2) -(node.width / 2);
								node.ox = left;
							}
						}
					}
				}
				
			}
			for (int j = max; j >= 0; j--) {
				List<TreeChartNode> row = new LinkedList(model.getRows().get(j).values());
				for (int i = 0; i < row.size(); i++) {
					TreeChartNode node = row.get(i);
					List<Object> list = node.rendered();
					data.addAll(list);
				}
			}

			/*
			for (int j = 0; j >= min; j--) {
				if (j == 0) continue;
				double top = (j - min) * (TreeChartCard.DEFAULT_HEIGHT + 20);
				double left = 0; 
				List<TreeChartNode> row = new LinkedList(model.getRows().get(j).values());
				System.out.println(j + " ("+top+") " + row);
			}
			*/
		} catch (Exception exc) {
			exc.printStackTrace();
		}
		return data; 
	}
	
	private void shiftChildrenRows(TreeChartNode parent, double o, int row, int col, int max) {
		if (col > 0) {
		} else {
			//shiftChildrenRows(o, row, col, max);
		}
	}
	
	private void shiftChildrenRows(double o, int row, int col, int max) {
		for (int j = row; j <= max; j++) {
			Vector<TreeChartNode> rowObj = new Vector<TreeChartNode>(model.getRows().get(j).values());
			for (int i = 0; i < rowObj.size(); i++) {
				TreeChartNode node = rowObj.get(i);
				node.ox += o;
			}
		}
	}
	/**
	 * 
	 */
	public TreeChartModel createModel() {
		try {
			model = new TreeChartModel();
			model.setRoot(root);
			model.setSelected(selected);
			model.build();
		} catch (Exception exc) {
			exc.printStackTrace();
		}
		return model;
	}
	
	// -----  -----------------------------------------------------------------
	
	public GedProject getProject() {
		return project;
	}
	
	public void setProject(GedProject project) {
		this.project = project;
	}
	
	public GedFamily getRoot() {
		return root;
	}
	
	public void setRoot(GedFamily family) {
		this.root = family;
	}
	
	public GedPerson getSelected() {
		return selected;
	}
	
	public void setSelected(GedPerson person) {
		this.selected = person;
	}

	public TreeChartModel getModel() {
		return model;
	}

	public void setModel(TreeChartModel model) {
		this.model = model;
	}
}
